#!/usr/bin/env ruby

#------------------------------------------------------------------#
#                                                                  #
#  @Authors                                                        #
#                                                                  #
#     - Almaraz Hernández, Jesús     (jesus.mah@gmail.com)         #
#     - Campos Cantero, Pablo        (camposc.pablo@gmail.com)     #
#     - Castelo Delgado, Tamara      (tcastelod@gmail.com)         #
#                                                                  #
#  @Supervisor                                                     #
#                                                                  #
#     - Santiago Montero, Rubén                                    #
#                                                                  #
#------------------------------------------------------------------#
require 'rubygems'
require 'sinatra'
require 'dataBase.rb'

use Rack::Session::Pool
##############################################################################
# Helpers
##############################################################################
helpers do
    def authorized?
	session["ip"] && session["ip"]==request.ip ? true : false
	
    end

    def build_session
        # El formulario de login debe mandar el usuario y password
        # con la extensión BasicAuth del protocolo HTTP

	auth = Rack::Auth::Basic::Request.new(request.env)

        if auth.provided? && auth.basic? && auth.credentials
            user = auth.credentials[0]
            sha1_pass = Digest::SHA1.hexdigest(auth.credentials[1])
		

            # Hacer la autorización con la base de datos
            authorization_level = authenticate(user,sha1_pass)

            if authorization_level
                
		session["user"]       	= user
                session["auth_level"]	= authorization_level
                session["password"]   	= sha1_pass
                session["ip"]         	= request.ip
		
		if params[:remember]=="true"
			# Set cookies for one month time expiration with user_id & password for autocomplete login form.
			time = Time.now + 60*60*24*30
    			response.set_cookie("Campus-Cloud-user_ID", 
                        		:value=>"#{session['user']}", 
                        		:expires=>time)

    			response.set_cookie("Campus-Cloud-user_pass", 
                        		:value=>"#{session['password']}", 
                        		:expires=>time)
		end

		# Return the client's request was successfully received, understood, and accepted. 
                return [204, ""]
            else
		# Return unauthorized HTTP status.
                return [401, ""]
            end

        end

        # Return unauthorized HTTP status.
        return [401, ""]	
   end


   def destroy_session
	session.clear
	return [204, ""]
   end

end

after do

	unless request.path=='/login'
		if authorized? == false
		# Time session expired. Authenticate must be necesary again.
        		env['rack.session.options'][:defer] = true
        	else
		# Reset time session to 10 minutes.
                	env['rack.session.options'][:expire_after] = 60*30
        	end
	end

end


##############################################################################
# HTML Requests
##############################################################################
get '/' do
	
    redirect '/login' unless authorized?

    #Send index.html

    File.read(File.dirname(__FILE__)+'/templates/index'+"#{session['auth_level']}"+'.html')

end

get '/login' do
    File.read(File.dirname(__FILE__)+'/templates/login.html')
end

##############################################################################
# Login & Logout
##############################################################################
post '/login' do
    build_session
	
end

post '/logout' do
    destroy_session
end

##############################################################################
# Students
##############################################################################

get '/students/:query' do

	return [401, ""] unless authorized?
 	
	if params[:query]=="list"
		return listLabsDel
	else
		return [404,"There are no actions defined for the request recived by server"]
	end
end

##############################################################################
# Teachers
##############################################################################

get '/teachers/:query' do
	
	return [401, ""] unless authorized?	

	if params[:query]=="list"	
		return listLabs
	elsif params[:query]=="create"
		return listTemplates
	elsif params[:query]=="delete"
		return listLabsID(session["user"])
	else
		return [404,"There are no actions defined for the request recived by server"]
	
	end	
end

post '/teachers/:query' do
	
	return[401, ""] unless authorized?
	
	begin

	##########  Try to execute the request  ##########
	if params[:query]=="create"
		newLab(params[:template],session["user"],params[:labName],params[:labGroup],params[:labDescription])
		return [204,""]	
	elsif params[:query]=="delete"
		deleteLab(params[:labID])
		return [204,""]
	else
		return [404,"There are no actions defined for the request recived by server"]
	
	end

	##########  Catch any exception throws by database  ##########
	rescue Exception
		return [404,"An error occurred when the server tried to execute the request"]
	end	
	
end

##############################################################################
# Administrators
##############################################################################

get '/administrators/:table/:action' do
		
	return[401, ""] unless authorized?

	if params[:table]=="students"	
		if params[:action]=="list"
			return listStudents
		elsif params[:action]=="delete"
			return listStudents	
		else
			return [404,"There are no actions defined for the request recived by server"]	
		end	
	elsif params[:table]=="teachers"	
		if params[:action]=="list"
			return listTeachers
		elsif params[:action]=="delete"
			return listTeachers	
		else
			return [404,"There are no actions defined for the request recived by server"]	
		end
	elsif params[:table]=="templates"	
		if params[:action]=="list"
			return listTemplates
		elsif params[:action]=="delete"
			return listTemplates	
		else
			return [404,"There are no actions defined for the request recived by server"]	
		end	
	elsif params[:table]=="labs"	
		if params[:action]=="list"
			return listLabs
		elsif params[:action]=="create"
			return listTemplates
		elsif params[:action]=="delete"
			return listLabsDel	
		else
			return [404,"There are no actions defined for the request recived by server"]	
		end
	else
		return [404,"There are no actions defined for the request recived by server"]	
	end
end

post '/administrators/:table/:action' do

	return[401, ""] unless authorized?

	begin

	##########  Try to execute the request  ##########
	if params[:table]=="students" 
		if params[:action]=="delete"
			deleteStudent(params[:ID])
			return [204,""]
		elsif params[:action]=="create"
			if newStudent(params[:ID],params[:name],params[:surname],params[:ID])
				return [404,"The ID alredy exists!"]
			else
				return [204,""]
			end
		else
			return [404,"There are no actions defined for the request recived by server"]	
		end
	elsif params[:table]=="teachers"
		if params[:action]=="delete"
			deleteTeacher(params[:ID])
			return [204,""]
		elsif params[:action]=="create"
			if newTeacher(params[:ID],params[:name],params[:surname],params[:ID])
				return [404,"The ID alredy exists!"]
			else
				return [204,""]
			end
		else
			return [404,"There are no actions defined for the request recived by server"]	
		end
	elsif params[:table]=="templates"
		if params[:action]=="delete"
			if deleteTemplate(params[:ID])
				return [404,"The template is alreday in use by some lab.<br><br>Please, delete the lab first"]
			else
				return [204,""]
			end
		elsif params[:action]=="create"
			newTemplate(params[:name],params[:description],params[:URI])
			return [204,""]
		else
			return [404,"There are no actions defined for the request recived by server"]	
		end
	elsif params[:table]=="labs"
		if params[:action]=="delete"
			deleteLab(params[:ID])
			return [204,""]
		elsif params[:action]=="create"
			newLab(params[:template],params[:teacher],params[:labName],params[:labGroup],params[:labDescription])
			return [204,""]	
		else
			return [404,"There are no actions defined for the request recived by server"]	
		end
	else
		return [404,"There are no actions defined for the request recived by server"]	
	end

	##########  Catch any exception throws by database  ##########
	rescue Exception
		return [404,"An error occurred when the server tried to execute the request"]
	end
end

##############################################################################
# Templates
##############################################################################

get '/templates' do
	
	return[401, ""] unless authorized?	

	@templates = getTemplates	
	return @templates
end

##############################################################################
# Labs
##############################################################################

get '/labs' do

	return[401, ""] unless authorized?
	
	@labs = listLabs	
	return @labs
end

##############################################################################
# Sessions
##############################################################################

get 'sessions' do
	
	@sessions = getSessions	
	return @sessions
end

